package com.giscloud.commons.utils;


import com.giscloud.commons.annotation.FieldAnnotation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.util.regex.Pattern.compile;

public class StringUtils extends org.apache.commons.lang3.StringUtils {
    private static final Logger log = LoggerFactory.getLogger(StringUtils.class);
    /**
     * 定义所有常量
     */
    public static final String EMPTY = "";
    public static final int ZERO = 0;
    public static final int ONE = 1;
    public static final int TWO = 2;
    public static final int THREE = 3;
    public static final int FOUR = 4;

    public static String formatDuring(long ms) {
        int ss = 1000;
        int mi = ss * 60;
        int hh = mi * 60;
        int dd = hh * 24;

        long day = ms / dd;
        long hour = (ms - day * dd) / hh;
        long minute = (ms - day * dd - hour * hh) / mi;
        long second = (ms - day * dd - hour * hh - minute * mi) / ss;
        long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;
        //天
        String strDay = day < 10 ? "0" + day : "" + day;
        //小时
        String strHour = hour < 10 ? "0" + hour : "" + hour;
        //分钟
        String strMinute = minute < 10 ? "0" + minute : "" + minute;
        //秒
        String strSecond = second < 10 ? "0" + second : "" + second;
        //毫秒
        String strMilliSecond = milliSecond < 10 ? "0" + milliSecond : "" + milliSecond;
        strMilliSecond = milliSecond < 100 ? "0" + strMilliSecond : "" + strMilliSecond;

        return strDay + " days " + strHour + " hours " + strMinute + " minutes "
                + strSecond + " seconds "+ strMilliSecond + " milliSecond ";
    }

    public static int getStringLength(String str, String encoding) {
        if(isEmpty(str)) {
            return 0;
        } else {
            try {
                return str.getBytes(encoding).length;
            } catch (UnsupportedEncodingException e) {
                log.error("异常："+e.getMessage());
                return 0;
            }
        }
    }


    /**
     * 通过对象获取注解以及值
     * @param object
     * @return
     */
    public static String getOldValue(Object object){
        StringBuffer sb = new StringBuffer();
        Field[] fields = object.getClass().getSuperclass().getDeclaredFields();
        Object value = "";
        try {
            for (Field field : fields) {
                boolean fieldHasAnno = field.isAnnotationPresent(FieldAnnotation.class);
                if (fieldHasAnno) {
                    FieldAnnotation fieldAnno = field.getAnnotation(FieldAnnotation.class);
                    String getMethodName = ListUtils.getMethodByFieldName(object.getClass(),field.getName()); //转换成字段的get方法
                    Method getMethod = object.getClass().getSuperclass().getMethod(getMethodName, new Class[]{});
                    //这个对象字段get方法的值
                    value = getMethod.invoke(object, new Object[]{});
                    //输出注解属性
                    String desc = fieldAnno.desc();
                    sb.append(desc + ":" + value + "\r\n");
                }
            }
        } catch (Exception e) {
            log.error("异常信息："+e.getMessage());
        }
        return sb.toString();

    }

    /**
     * 创建指定数量的随机字符串
     *
     * @param isNumber 是否是数字
     * @param length
     * @return
     */
    public static String randomStr(boolean isNumber, int length) {
        String retStr = "";
        String strTable = isNumber ? "1234567890" : "1234567890abcdefghijkmnpqrstuvwxyz";
        int len = strTable.length();
        boolean bDone = true;
        do {
            retStr = "";
            int count = 0;
            for (int i = 0; i < length; i++) {
                double dblR = Math.random() * len;
                int intR = (int) Math.floor(dblR);
                char c = strTable.charAt(intR);
                if (('0' <= c) && (c <= '9')) {
                    count++;
                }
                retStr += strTable.charAt(intR);
            }
            if (count >= 2) {
                bDone = false;
            }
        } while (bDone);

        return retStr;
    }


    /**
     * 获取第三次出“/”的位置（http://127.0.0.1:8080/test）
     * @param str
     * @return
     */
    public static int getCharacterPosition(String str){
        //这里是获取"/"符号的位置
        Matcher slashMatcher = compile("/").matcher(str);
        int mIdx = 0;
        while(slashMatcher.find()) {
            mIdx++;
            //当"/"符号第三次出现的位置
            if(mIdx == 3){
                break;
            }
        }
        if(mIdx != 3){
            return str.length();
        }
        return slashMatcher.start();
    }

    /**
     * 获取第n次出str的位置（http://127.0.0.1:8080/test）
     * @param str
     * @param index
     * @return
     */
    public static int getCharacterPosition(String str,int index){
        //这里是获取"/"符号的位置
        Matcher slashMatcher = compile("/").matcher(str);
        int mIdx = 0;
        while(slashMatcher.find()) {
            mIdx++;
            //当"/"符号第三次出现的位置
            if(mIdx == index){
                break;
            }
        }
        if(mIdx != index){
            return str.length();
        }
        return slashMatcher.start();
    }

    /**
     * 获取第n次出str的位置（http://127.0.0.1:8080/test）
     * @param str
     * @param separator
     * @param index
     * @return
     */
    public static int getCharacterPosition(String str,String separator,int index){
        //这里是获取"/"符号的位置
        Matcher slashMatcher = compile(separator).matcher(str);
        int mIdx = 0;
        while(slashMatcher.find()) {
            mIdx++;
            //当"/"符号第三次出现的位置
            if(mIdx == index){
                break;
            }
        }
        if(mIdx != index){
            return str.length();
        }
        return slashMatcher.start();
    }

    public static boolean isEmpty(String[] values) {
        if (values == null || values.length == 0) {
            return true;
        }
        for (String value : values) {
            if (!isEmpty(value)) {
                return false;
            }
        }
        return true;
    }

    /**
     * @Description 字符串向左截取
     * @author ShengLiu
     * @date 2018/7/4
     * @param str
     * @param len
     * @return java.lang.String
     */
    public static String left(String str, int len) {
        if (str == null) {
            return null;
        }
        if (len < ZERO) {
            return EMPTY;
        }
        if (str.length() <= len) {
            return str;
        }
        return str.substring(ZERO, len);

    }

    /**
     * @Description 字符串向右截取
     * @author ShengLiu
     * @date 2018/7/4
     * @param str
     * @param len
     * @return java.lang.String
     */
    public static String right(String str, int len) {
        if (str == null) {
            return null;
        }
        if (len < ZERO) {
            return EMPTY;
        }
        if (str.length() <= len) {
            return str;
        }
        return str.substring(str.length() - len);

    }

    /**
     * 根据用户名的不同长度，来进行替换 ，达到保密效果
     *
     * @param userName 用户名
     * @return 替换后的用户名
     */
    public static String userNameReplaceWithStar(String userName) {
        if(userName == null){
            return null;
        }
        if(userName.length() == ONE) {
            return userName;
        }else if(userName.length() == TWO){
            return  left(userName, ONE)+"*" ;
        }else if(userName.length() == THREE){
            return left(userName, ONE) + "**";
        }else if(userName.length() == FOUR){
            return left(userName, ONE) + "**" + right(userName, ONE);
        }else {
            return left(userName, ONE) + "***" + right(userName, ONE);
        }
    }

    /**
     * 实际替换动作
     *
     * @param source source
     * @param regular  正则
     * @return
     */
    private static String replaceAction(String source, String regular,String replaceSymbol) {
        return source.replaceAll(regular, replaceSymbol);
    }

    /**
     * 身份证号替换，保留前四位和后四位
     *
     * 如果身份证号为空 或者 null ,返回null ；否则，返回替换后的字符串；
     *
     * @param idCard 身份证号
     * @return
     */
    public static String idCardReplaceWithStar(String idCard) {

        if (isBlank(idCard)) {
            return null;
        } else {
            return replaceAction(idCard, "(\\d{4})\\d{10}(\\w{4})", "$1*****$2");
        }
    }

    /**
     * 银行卡替换，保留后四位
     *
     * 如果银行卡号为空 或者 null ,返回null ；否则，返回替换后的字符串；
     *
     * @param bankCard 银行卡号
     * @return
     */
    public static String bankCardReplaceWithStar(String bankCard) {

        if (isBlank(bankCard)) {
            return "未绑定";
        } else {
            int length = bankCard.length();
            if (length > 4) {
                String startNum = bankCard.substring(0, 4);
                String endNum = bankCard.substring(length - 4, length);
                bankCard = startNum + "********" + endNum;
            }
            return bankCard;
        }
    }

    public static String telphoneReplaceWithStar(String telphone) {

        if (isBlank(telphone)) {
            return null;
        } else {
            return replaceAction(telphone,"(\\d{3})\\d{4}(\\d{4})", "$1****$2");
        }
    }
    public static String getUrlPrefix(String url) {
        // 正则表达式规则
        String regEx = "((http|ftp|https)://)(([a-zA-Z0-9._-]+)|([0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}))(([a-zA-Z]{2,6})|(:[0-9]{1,4})?)";
        // 编译正则表达式
        Pattern pattern = Pattern.compile(regEx);
        // 忽略大小写的写法
        Matcher m = pattern.matcher(url);
        // 查找字符串中是否有匹配正则表达式的字符/字符串
        while (m.find()) {
            return m.group();
        }

        return "";
    }
    public static boolean checkMobilePhoneNum(String phoneNum) {
        String regex = "^(1[3-9]\\d{9}$)";
        if (phoneNum.length() == 11) {
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(phoneNum);
            if (m.matches()) {
                return true;
            }
        }
        return false;
    }
    public static void main(String[] args)
    {
        Random random=new Random();

        List<Integer> list=new ArrayList<>();
        for(int i=0;i<10000000;i++)
        {
            int randomResult=random.nextInt(100000000);
            list.add(randomResult);
        }
        System.out.println("产生的随机数有");
        for(int i=0;i<list.size();i++)
        {
            System.out.println(list.get(i));
        }
        BitSet bitSet=new BitSet(100000000);
        for(int i=0;i<10000000;i++)
        {
            bitSet.set(list.get(i));
        }

        System.out.println("0~1亿不在上述随机数中有"+bitSet.cardinality());
        for (int i = 0; i < 100000000; i++)
        {
            if(!bitSet.get(i))
            {
                System.out.println(i);
            }
        }
    }


}
